package com.jubaozan.service.platform.modules.store;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jubaozan.dao.columns.Columns;
import com.jubaozan.dao.youme.domain.Store;
import com.jubaozan.dao.youme.domain.StoreUser;
import com.jubaozan.dao.youme.service.StoreService;
import com.jubaozan.dao.youme.service.StoreUserService;
import com.jubaozan.feign.level.LevelFeignService;
import com.jubaozan.feign.level.vo.LevelVO;
import com.jubaozan.feign.login.vo.LoginVO;
import com.jubaozan.feign.user.UserFeignService;
import com.jubaozan.feign.user.vo.UserVO;
import com.jubaozan.service.platform.constants.LevelWeightEnum;
import com.jubaozan.service.platform.exception.PlatformException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author yuanjie
 */
@Slf4j
@CacheConfig(cacheNames = "STORE")
@Service
public class StoreCacheService {
    private final StoreService storeService;
    private final StoreUserService storeUserService;
    private final LevelFeignService levelFeignService;
    private final UserFeignService userFeignService;

    public StoreCacheService(StoreService storeService, StoreUserService storeUserService, LevelFeignService levelFeignService, UserFeignService userFeignService) {
        this.storeService = storeService;
        this.storeUserService = storeUserService;
        this.levelFeignService = levelFeignService;
        this.userFeignService = userFeignService;
    }

    private LevelVO getFansLevel(Long storeId) {
        return levelFeignService.queryLevel(LevelWeightEnum.FANS.getValue(), storeId)
                .map(level -> {
                    logger.debug("查询粉丝等级: {} {}", level, storeId);
                    return level;
                }).orElseThrow(() -> new PlatformException("没有可用的粉丝等级"));
    }

    @Cacheable(key = "#storeId", unless = "#result == null")
    public Store getStoreById(Long storeId) {
        return storeService.getById(storeId);
    }

    public Store getStoreByUserId(Long userId) {
        QueryWrapper<Store> wa = new QueryWrapper<>();
        wa.lambda().eq(Store::getUserId, userId);
        return storeService.getOne(wa);
    }


    @Cacheable(key = "'USER:' + #storeId + ':' + #userId", unless = "#result == null")
    public StoreUser queryStoreUser(Long userId, Long storeId) {
        QueryWrapper<StoreUser> wa = new QueryWrapper<>();
        wa.lambda().eq(StoreUser::getUserId, userId)
                .eq(StoreUser::getStoreId, storeId);
        return storeUserService.getOne(wa);
    }

    private String makeRemarks(UserVO fans, UserVO referee, LevelVO level) {
        logger.info("创建fans remarks: {} {} {}", fans, referee, level);
        JSONObject target = new JSONObject();
        target.put(Columns.NICK, fans.getNick());
        target.put(Columns.NAME, fans.getName());
        target.put(Columns.WEIGHT, level.getWeight());
        target.put(Columns.LEVEL_ID, level.getId());
        if (Objects.nonNull(referee)) {
            target.put(Columns.REFEREE_ID, referee.getId());
            target.put(Columns.REFEREE_NAME, referee.getName());
        }
        return target.toJSONString();
    }

    public void saveFans(UserVO user, Long storeId, LoginVO login) {
        StoreUser existsFans = queryStoreUser(user.getId(), storeId);
        if (Objects.nonNull(existsFans)) {
            return;
        }

        LevelVO level = getFansLevel(storeId);
        StoreUser fans = new StoreUser();
        fans.setStoreId(storeId);
        fans.setLevelId(level.getId());
        fans.setUserId(user.getId());

        if (login.getRefereeId() > 0) {
            userFeignService.getUserById(login.getRefereeId()).map(referee -> {
                logger.info("推荐人信息: {}", referee);
                fans.setRefereeId(referee.getId());
                fans.setRemarks(makeRemarks(user, referee, level));
                return referee;
            }).orElseThrow(() -> {
                logger.warn("推荐人不存在: {}", login.getRefereeId());
                return new PlatformException("推荐人不存在:" + login.getRefereeId());
            });
        } else {
            fans.setRemarks(makeRemarks(user, null, level));
        }
        storeUserService.save(fans);
    }
}
